package robotleMvc.frameworks.scene3D
{
	import _Pan3D.core.MathCore;
	import _Pan3D.display3D.Display3DContainer;
	import _Pan3D.display3D.Display3DMovie;
	import _Pan3D.program.Program3DManager;
	import _Pan3D.program.shaders.Md5Shader;
	import _Pan3D.texture.TextureManager;
	
	import _me.Config;
	import _me.KeyControl;
	import _me.Scene_data;
	
	import com.adobe.utils.PerspectiveMatrix3D;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Stage;
	import flash.display3D.Context3D;
	import flash.display3D.Context3DBlendFactor;
	import flash.display3D.Context3DCompareMode;
	import flash.display3D.Context3DProgramType;
	import flash.display3D.Context3DTriangleFace;
	import flash.display3D.Program3D;
	import flash.events.Event;
	import flash.filters.BitmapFilterQuality;
	import flash.filters.BlurFilter;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	import org.robotlegs.mvcs.Mediator;
	
	import robotleMvc.frameworks.GroundDisplay3DContainer;
	import robotleMvc.frameworks.ambience.AmbienceModel;
	import robotleMvc.frameworks.lightscene.LightsceneModel;
	import robotleMvc.frameworks.scene3D.event.Scene3DEvent;
	import robotleMvc.frameworks.scene3D.model.Scene3DModel;
	import robotleMvc.ui.Ground.GroundView;
	import robotleMvc.ui.build.BuildView;
	import robotleMvc.ui.glass.GlassDisplay3DContainer;
	import robotleMvc.ui.glass.GlassView;
	import robotleMvc.ui.lizhi.LizhiView;
	import robotleMvc.ui.lizhi.fensan.FensanView;
	import robotleMvc.ui.scene3D.Scene3DView;
	import robotleMvc.ui.tieXiao.TieXiaoView;
	import robotleMvc.ui.tree.TreeView;
	
	import test.vo.PersonSprite;
	import test.zhuwei.BuildDisplay3DContainer;
	import test.zhuwei.TreeDisplay3DContainer;
	import _Pan3D.base.Focus3D;

	// --------------MSN:lation_pan@live.cn  QQ: 3423526------------- //
	public class Scene3DMediator extends Mediator
	{

		public function Scene3DMediator()
		{
			super();
		}

		[Inject]
		public var scene3DModel:Scene3DModel;
		[Inject]
		public var ambienceModel:AmbienceModel;
		[Inject]
		public var lightsceneModel:LightsceneModel;
		[Inject]
		public var stage3dSceneView:Scene3DView;
		private var _bitmap:Bitmap;
		private var _build3DContainer:BuildDisplay3DContainer;
		private var _buildView:BuildView;
		private var _treeDisplay3DContainer:TreeDisplay3DContainer;
		private var _treeView:TreeView;
		private var _context3D:Context3D;
		private var _fensanContainer:Display3DContainer;
		private var _fensanView:FensanView;
		private var _glassContainer:GlassDisplay3DContainer;
		private var _glassView:GlassView;
		private var _groundContainer:GroundDisplay3DContainer;
		private var _groundDispy:GroundView;
		private var _keyControl:KeyControl=new KeyControl();
		private var _lizhiView:LizhiView;
		private var _programMd5:Program3D;
		private var _projMatrix:PerspectiveMatrix3D;
		private var _tiexiaoContainer:Display3DContainer;
		private var _tiexiaoDispy:TieXiaoView;

		private var openAll:Boolean=true;



		public function get context3D():Context3D
		{
			return _context3D;
		}

		override public function onRegister():void
		{
			initData();
			this.addContextListener(Scene3DEvent.GET_SHODAR_BITMAPDATA, getShodarBitMapData);
			this.addContextListener(Scene3DEvent.GET_GROUND_HEIGHT_BITMAPDATA, getGroundHeightBitmapData);

		}

		private function _config_end():void
		{
			_context3D=Scene_data.context3D;
			TextureManager.getInstance().init(context3D);
			makeScene();
			scene3DModel.initData(context3D);
			ambienceModel.initData(context3D)
			lightsceneModel.initData(context3D)
			addMd5Model();

		}

		private function addBuilds():void
		{
			_build3DContainer=new BuildDisplay3DContainer();
			_buildView=new BuildView(context3D, _build3DContainer);
			stage3dSceneView.addChild(_buildView);
		}

		private function addTrees():void
		{
			_treeDisplay3DContainer=new TreeDisplay3DContainer();
			_treeView=new TreeView(context3D, _treeDisplay3DContainer);
			stage3dSceneView.addChild(_treeView);
		}

		private function addFensanLizhi():void
		{
			_fensanContainer=new Display3DContainer();
			_fensanView=new FensanView(context3D, _fensanContainer);
			stage3dSceneView.addChild(_fensanView);

		}
		

		private function addGlassContainer():void
		{
			_glassContainer=new GlassDisplay3DContainer();
			_glassView=new GlassView(context3D, _glassContainer);
			stage3dSceneView.addChild(_glassView);

		}

		private function addGrounds():void
		{
			_groundContainer=new GroundDisplay3DContainer();
			_groundDispy=new GroundView(context3D, _groundContainer);
			stage3dSceneView.addChild(_groundDispy);
		}

		private function addLiZhis():void
		{
			_lizhiView=new LizhiView(context3D)
			stage3dSceneView.addChild(_lizhiView);
		}

		private function addTieXiaos():void
		{
			_tiexiaoContainer=new Display3DContainer();
			_tiexiaoDispy=new TieXiaoView(context3D, _tiexiaoContainer);
			stage3dSceneView.addChild(_tiexiaoDispy);
		}
		private var _md5container : Display3DContainer;
		private var _guaiwuMd5Mode:PersonSprite;
		private function addMd5Model():void
		{
			var context3D : Context3D = Scene_data.context3D;
			_guaiwuMd5Mode = new PersonSprite(context3D);
			_guaiwuMd5Mode.addMesh("0", "xingzou");
			_guaiwuMd5Mode.addAnim("xingzou", "xingzou");
			_guaiwuMd5Mode.initStage(Scene_data.stage);
			
			_guaiwuMd5Mode.scale=0.2
			_guaiwuMd5Mode.x=500
			_guaiwuMd5Mode.y=-8
			_guaiwuMd5Mode.z=600
			_guaiwuMd5Mode.rotationY=125
			_md5container=new Display3DContainer;
			_md5container.addChild(_guaiwuMd5Mode);
			var md5Program:Program3D = Program3DManager.getInstance().getProgram(Md5Shader.MD5SHADER);
			_guaiwuMd5Mode.setProgram3D(md5Program);
			
			
		}

		private function enterFrame(event:Event):void
		{
			
			if (!Scene_data.ready)
			{
				return;
			}
			//_keyControl.upData();
			
			//lightsceneModel.updata(context3D);

			//ambienceModel.updata(context3D);//扫描。地面叠加效果
	
			MathCore._catch_cam(Scene_data.cam3D, Scene_data.focus3D);
			context3D.clear(0, 0, 0, 1);
			_projMatrix=new PerspectiveMatrix3D();
			_projMatrix.perspectiveFieldOfViewLH(1, 1, 0.1, 9000);
			context3D.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, _projMatrix, true);

			Scene_data.context3D.setCulling(Context3DTriangleFace.BACK);
			context3D.setBlendFactors(Context3DBlendFactor.ONE, Context3DBlendFactor.ZERO);
			context3D.setDepthTest(true, Context3DCompareMode.LESS);
			openAll ? _build3DContainer.update() : null;
			openAll ? _groundContainer.update() : null;
			Scene_data.context3D.setCulling(Context3DTriangleFace.NONE);
			_treeDisplay3DContainer.update();
			_md5container.update();
			
			scene3DModel.showGlassView ? _glassContainer.update() : null;
		
			
			/*
			context3D.setDepthTest(false, Context3DCompareMode.GREATER);
			context3D.setBlendFactors(Context3DBlendFactor.		SOURCE_ALPHA, Context3DBlendFactor.	SOURCE_ALPHA);
			_treeDisplay3DContainer.update();

			context3D.setDepthTest(true, Context3DCompareMode.LESS);
			context3D.setBlendFactors(Context3DBlendFactor.ONE, Context3DBlendFactor.ZERO);
			_treeDisplay3DContainer.update();
			
			*/

			Scene_data.context3D.setCulling(Context3DTriangleFace.NONE);
			context3D.setBlendFactors(Context3DBlendFactor.SOURCE_ALPHA, Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA);
			context3D.setDepthTest(false, Context3DCompareMode.LESS);
			openAll ? _lizhiView.updata() : null;
			openAll ? _fensanContainer.update() : null;
			openAll ? _tiexiaoContainer.update() : null;

			context3D.present();
			
			scene3DModel.makeLightCam();


		}

		private function getGroundHeightBitmapData(scene3d:Scene3DEvent):void
		{

			getGroundHightMap();


		}

		private function getGroundHightMap():void
		{

			var tempBitMap:BitmapData=_groundContainer.scanningGroundHight(context3D);
			var evt:Scene3DEvent=new Scene3DEvent(Scene3DEvent.SEND_GROUND_HEIGHT_BITMAPDATA);
			evt.groundHeightBitmapData=tempBitMap;
			this.dispatch(evt);
			Config.restConfigContext3D();

		}

		private function getShodarBitMapData(scene3d:Scene3DEvent):void
		{
			Scene_data.sun3D=Scene_data.cam3D.clone();
			var fous3D:Focus3D=Scene_data.focus3D.cloneFocus3D();
			Scene_data.sun3D.distance=2470
			fous3D.x=382
			fous3D.y=0
			fous3D.z=623
			fous3D.angle_x=-90;
			fous3D.angle_y=311;
			MathCore._catch_cam(Scene_data.sun3D, fous3D);
			
			
			var shadowBitmapData0:BitmapData=_treeDisplay3DContainer.scaningShadow(context3D);  //有点奇，还要修改的地方
			var shadowBitmapData:BitmapData=new BitmapData(1024,1024,false,0xffffff)//先保证是白的基础色表示没有
			shadowBitmapData.draw(_build3DContainer.scaningShadow(context3D));//得到建筑的阴影
			shadowBitmapData.draw(_treeDisplay3DContainer.scaningShadow(context3D));//得到树的阴影
			var filter:BlurFilter = new BlurFilter(3,3,BitmapFilterQuality.HIGH);
			shadowBitmapData.applyFilter(shadowBitmapData,new Rectangle(0,0,shadowBitmapData.width,shadowBitmapData.height),new Point,filter);

			
			
			Scene_data.texShadowMap.uploadFromBitmapData(shadowBitmapData);
			context3D.configureBackBuffer(1024, 600, 1, true);
			context3D.setCulling(Context3DTriangleFace.NONE);

			var evt:Scene3DEvent=new Scene3DEvent(Scene3DEvent.SEND_GROUND_HEIGHT_BITMAPDATA);
			evt.groundHeightBitmapData=shadowBitmapData;
			this.dispatch(evt);

		}

		private function initData():void
		{
			Scene_data.fileRoot="../_File/nijia2/";
			//Scene_data.fileRoot="http://pan3dme.lt6.nns.cc/pan3D/yizhan/_File/nijia2/";
			var stage:Stage=Scene_data.stage;
			Config.init(stage, _config_end);
			_keyControl.init(stage);
		}

		private function makeScene():void
		{
			addGrounds();
			addBuilds();
			addTrees();
			addTieXiaos();
			addLiZhis();
			addFensanLizhi();
			addGlassContainer()
			Scene_data.cam3D.distance=500;
			Scene_data.focus3D.angle_y=-125;
			Scene_data.focus3D.angle_x=-30;
			Scene_data.focus3D.x=0;
			Scene_data.focus3D.y=0;
			Scene_data.focus3D.z=0;

			var stage:Stage=Scene_data.stage;
			stage.addEventListener(Event.ENTER_FRAME, enterFrame);
		}


	}
}
